/* 
 * File:   Taylor_exp.cpp
 * Author: jorgeorm
 * 
 * Created on 28 de agosto de 2011, 07:29 PM
 */

#include "Taylor_exp.h"

#include <cstdlib>
#include <stdio.h>
#include <iostream>
#include <stdlib.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include <cstdio>

long int factorial (int n)
{
    long int resultado=1;
    for(int n_esimo=n;n_esimo>1;n_esimo--)
    {
        resultado=resultado*(long int)n_esimo;
    }
    return resultado;
}

Taylor_exp::Taylor_exp(int tamanoDatos, int a1, int a2, int a3, const char * nombreArchiv) {
                      
    //  InitDAtos
  a_taylor=new int [3];
  a_taylor[0]=a1;
  a_taylor[1]=a2;
  a_taylor[2]=a3;
  tam_prueba=tamanoDatos;
  arrayDatos=new double[tam_prueba];
  arrayResults=new double[tam_prueba];
  arrayResultsTaylor=new double * [tam_prueba];
  for(int idfilas =0;idfilas <tam_prueba; idfilas++)
  {
      arrayResultsTaylor[idfilas]=new double[3];
      for( int idCol=0; idCol<3; idCol++)
      {
          arrayResultsTaylor[idfilas][idCol]=0.0;
      }
  }
//  strcat(nombreArchivo,nombreArchiv);
  
//  inicializo el nombre del archivo

  
//  abro archivo
  //output=fopen("resultados.txt","ab+");
  //if(output==NULL)
//  output= fopen(nombreArchivo,"wb+");
  
//  for(int i=0; i< tam_prueba; i++){
//      if (i<(tam_prueba-1))cout<<arrayDatos[i]<<", ";
//      else cout<<arrayDatos[i]<<endl;
//  }
}

//Taylor_exp::Taylor_exp(const Taylor_exp& orig) {
//}

Taylor_exp::~Taylor_exp() {
//    Destruyo arreglos y objetos
    delete []arrayDatos;
    delete []arrayResults;
    delete ptr_output;
    
//TODO: Borrar matriz de resultado
    
//    Aterrizo a NULL
    arrayDatos=NULL;
    arrayResults=NULL;
    delete []a_taylor;
    tam_prueba=0;
    truncar=0;
}


//--------------_Iplementación de los métodos

void Taylor_exp::escribirResultadosTaylor(){
    
    ptr_output= fopen("resultados.txt","ab+");//Abro el archivo
    
    fprintf(ptr_output,"---------------------FUNCIÓN EULER TAYLOR---------------------\n");
    fprintf(ptr_output,"--------------------------------------------------------------\n");
    fprintf(ptr_output,"**********************Se truncó en n= %i *********************\n",truncar);

    for(int a_i=0;a_i<3;a_i++)
    {
        fprintf(ptr_output,"****************Tomó como valor a: %i\n",a_taylor[a_i]);
        fprintf(ptr_output, "x\t y\n");
        for(int i=0;i<tam_prueba;i++)
        {
            // Entradas fprintf: archivo, estructura (%f:float), datos a escribir.
            fprintf(ptr_output,"%f\t ",arrayDatos[i]);
            fprintf(ptr_output,"%f\n",arrayResultsTaylor[i][a_i]);
        }
        fprintf(ptr_output,"\n");
    }
    
    //Cierro archivo
    fclose(ptr_output);
}

void Taylor_exp::escribirResultadosCPP(){//    escribo los valores con separados por caracter.
    //abro archivo
//    output=fopen("resultados.txt","ab+");
//    if(output==NULL) 
    ptr_output= fopen("resultados.txt","wb+");
    
    fprintf(ptr_output,"-----------------------FUNCIÓN EULER CPP----------------------\n");
    fprintf(ptr_output,"--------------------------------------------------------------\n");
    fprintf(ptr_output, "x\t y\n");
    for(int i=0;i<tam_prueba;i++)
    {
        // Entradas fprintf: archivo, estructura (%f:float), datos a escribir.
        fprintf(ptr_output,"%f\t ",arrayDatos[i]);
        fprintf(ptr_output,"%f\n",arrayResults[i]);
    }
    
    
    //Cierro archivo
    fclose(ptr_output);
}

void Taylor_exp::inicializarDatosPrueba(){
    srand(time(NULL)); // Instancia semilla random
    cout <<"-------------------------InicializarDatos"<<endl;  
//Se inicializa el arreglo
    for(int i=0; i< tam_prueba; i++){
      arrayDatos[i] = ((double)rand()/(double)RAND_MAX)*10.0;
//      arrayResults[i]= exp(arrayDatos[i]);
      //imprimo array
//      cout<<arrayDatos[i];
//      if(i<(tam_prueba-1))cout<<", ";
//      else cout<<endl;
    }
    
}

void Taylor_exp::calcularExponencialCpp(){
//Se evalua la función de cpp, y la serie truncada y asignan los valores
    cout <<"-------------------------calcularExponencial"<<endl;      

    for(int i=0;i<tam_prueba; i++){
        //evaluación de cpp
        arrayResults[i]= exp(arrayDatos[i]);
//        cout<<arrayDatos[i]<<", "<<arrayResults[i]<<endl;

    }
}

void Taylor_exp::calcularExponencialTaylor(int truncarEn){
    cout<<"--------------------------calcularExponencialConTaylor"<<endl;
    
    truncar = truncarEn;
    for(int a_i=0;a_i<3;a_i++)
    {
        for(int y_i=0;y_i<tam_prueba;y_i++)
        {
            double resta=(arrayDatos[y_i]-(double)a_taylor[a_i]);
            
            for(int i=0;i<=truncar;i++)
            {
//                cout<<"resta de x-a: "<<resta<<", ";
                long double factorialsito=(long double)factorial(i);
                long double division=(pow( (long double)resta, i )/factorialsito);
//                cout<<"división ((x-a)^i)/i!: "<<division<<", ";
//                cout<<"factorial i!: "<<factorialsito<<endl;
                arrayResultsTaylor[y_i][a_i]+=(double)(division*exp((long double)a_taylor[a_i]));
            }
        }
    }
}

